/*
 * Copyright 2008 Zoundry LLC, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 */
package org.zoundry.gaedt.ui.editors.operations;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.zoundry.gaedt.core.models.application.IZGaeHandlerModel;
import org.zoundry.gaedt.core.models.application.ZGaeApplicationModel;

/**
 * An operation used to reposition a handler within a list of handlers.
 */
public class ZGaeMoveHandlerOperation extends ZGaeAbstractUndoableOperation implements IZGaeUndoableOperation
{
    /** The application model that owns/contains the handler. */
    private ZGaeApplicationModel mApplicationModel;
    /** The handler being moved. */
    private IZGaeHandlerModel mHandlerModel;
    /** The amount and direction for the move. */
    private int mMovementSpec;

    /**
     * C'tor.
     *
     * @param aUndoLabel
     * @param aApplicationModel
     * @param aHandlerModel
     * @param aMovementSpec
     * @param aUIUpdater
     */
    public ZGaeMoveHandlerOperation(String aUndoLabel, ZGaeApplicationModel aApplicationModel,
            IZGaeHandlerModel aHandlerModel, int aMovementSpec, IZGaeUIUpdater aUIUpdater)
    {
        super(aUndoLabel, aUIUpdater);
        setApplicationModel(aApplicationModel);
        setHandlerModel(aHandlerModel);
        setMovementSpec(aMovementSpec);
    }

    /**
     * @see org.zoundry.gaedt.ui.editors.operations.IZGaeUndoableOperation#shouldExecute()
     */
    public boolean shouldExecute()
    {
        return true;
    }

    /**
     * @see org.eclipse.core.commands.operations.AbstractOperation#execute(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.core.runtime.IAdaptable)
     */
    @Override
    public IStatus execute(IProgressMonitor aMonitor, IAdaptable aInfo) throws ExecutionException
    {
        int newIndex = getApplicationModel().move(getHandlerModel(), getMovementSpec());
        getUIUpdater().updateUIForExecute(newIndex);
        return Status.OK_STATUS;
    }

    /**
     * @see org.eclipse.core.commands.operations.AbstractOperation#redo(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.core.runtime.IAdaptable)
     */
    @Override
    public IStatus redo(IProgressMonitor aMonitor, IAdaptable aInfo) throws ExecutionException
    {
        int newIndex = getApplicationModel().move(getHandlerModel(), getMovementSpec());
        getUIUpdater().updateUIForRedo(newIndex);
        return Status.OK_STATUS;
    }

    /**
     * @see org.eclipse.core.commands.operations.AbstractOperation#undo(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.core.runtime.IAdaptable)
     */
    @Override
    public IStatus undo(IProgressMonitor aMonitor, IAdaptable aInfo) throws ExecutionException
    {
        // Move the item in the other direction
        int newIndex = getApplicationModel().move(getHandlerModel(), getMovementSpec() * -1);
        getUIUpdater().updateUIForUndo(newIndex);
        return Status.OK_STATUS;
    }

    /**
     * @return the applicationModel
     */
    protected ZGaeApplicationModel getApplicationModel()
    {
        return mApplicationModel;
    }

    /**
     * @param aApplicationModel the applicationModel to set
     */
    protected void setApplicationModel(ZGaeApplicationModel aApplicationModel)
    {
        mApplicationModel = aApplicationModel;
    }

    /**
     * @return the handlerModel
     */
    protected IZGaeHandlerModel getHandlerModel()
    {
        return mHandlerModel;
    }

    /**
     * @param aHandlerModel the handlerModel to set
     */
    protected void setHandlerModel(IZGaeHandlerModel aHandlerModel)
    {
        mHandlerModel = aHandlerModel;
    }

    /**
     * @return the movementSpec
     */
    protected int getMovementSpec()
    {
        return mMovementSpec;
    }

    /**
     * @param aMovementSpec the movementSpec to set
     */
    protected void setMovementSpec(int aMovementSpec)
    {
        mMovementSpec = aMovementSpec;
    }
}
